home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / share / perl5 / HTTP / Message.pm < prev    next >
Text File  |  2008-04-16  |  20KB  |  763 lines

  1. package HTTP::Message;
  2.  
  3. use strict;
  4. use vars qw($VERSION $AUTOLOAD);
  5. $VERSION = "5.812";
  6.  
  7. require HTTP::Headers;
  8. require Carp;
  9.  
  10. my $CRLF = "\015\012";   # "\r\n" is not portable
  11. $HTTP::URI_CLASS ||= $ENV{PERL_HTTP_URI_CLASS} || "URI";
  12. eval "require $HTTP::URI_CLASS"; die $@ if $@;
  13.  
  14. *_utf8_downgrade = defined(&utf8::downgrade) ?
  15.     sub {
  16.         utf8::downgrade($_[0], 1) or
  17.             Carp::croak("HTTP::Message content must be bytes")
  18.     }
  19.     :
  20.     sub {
  21.     };
  22.  
  23. sub new
  24. {
  25.     my($class, $header, $content) = @_;
  26.     if (defined $header) {
  27.     Carp::croak("Bad header argument") unless ref $header;
  28.         if (ref($header) eq "ARRAY") {
  29.         $header = HTTP::Headers->new(@$header);
  30.     }
  31.     else {
  32.         $header = $header->clone;
  33.     }
  34.     }
  35.     else {
  36.     $header = HTTP::Headers->new;
  37.     }
  38.     if (defined $content) {
  39.         _utf8_downgrade($content);
  40.     }
  41.     else {
  42.         $content = '';
  43.     }
  44.  
  45.     bless {
  46.     '_headers' => $header,
  47.     '_content' => $content,
  48.     }, $class;
  49. }
  50.  
  51.  
  52. sub parse
  53. {
  54.     my($class, $str) = @_;
  55.  
  56.     my @hdr;
  57.     while (1) {
  58.     if ($str =~ s/^([^\s:]+)[ \t]*: ?(.*)\n?//) {
  59.         push(@hdr, $1, $2);
  60.         $hdr[-1] =~ s/\r\z//;
  61.     }
  62.     elsif (@hdr && $str =~ s/^([ \t].*)\n?//) {
  63.         $hdr[-1] .= "\n$1";
  64.         $hdr[-1] =~ s/\r\z//;
  65.     }
  66.     else {
  67.         $str =~ s/^\r?\n//;
  68.         last;
  69.     }
  70.     }
  71.  
  72.     new($class, \@hdr, $str);
  73. }
  74.  
  75.  
  76. sub clone
  77. {
  78.     my $self  = shift;
  79.     my $clone = HTTP::Message->new($self->headers,
  80.                    $self->content);
  81.     $clone->protocol($self->protocol);
  82.     $clone;
  83. }
  84.  
  85.  
  86. sub clear {
  87.     my $self = shift;
  88.     $self->{_headers}->clear;
  89.     $self->content("");
  90.     delete $self->{_parts};
  91.     return;
  92. }
  93.  
  94.  
  95. sub protocol { shift->_elem('_protocol',  @_); }
  96.  
  97. sub content  {
  98.  
  99.     my $self = $_[0];
  100.     if (defined(wantarray)) {
  101.     $self->_content unless exists $self->{_content};
  102.     my $old = $self->{_content};
  103.     $old = $$old if ref($old) eq "SCALAR";
  104.     &_set_content if @_ > 1;
  105.     return $old;
  106.     }
  107.  
  108.     if (@_ > 1) {
  109.     &_set_content;
  110.     }
  111.     else {
  112.     Carp::carp("Useless content call in void context") if $^W;
  113.     }
  114. }
  115.  
  116. sub _set_content {
  117.     my $self = $_[0];
  118.     _utf8_downgrade($_[1]);
  119.     if (!ref($_[1]) && ref($self->{_content}) eq "SCALAR") {
  120.     ${$self->{_content}} = $_[1];
  121.     }
  122.     else {
  123.     die "Can't set content to be a scalar reference" if ref($_[1]) eq "SCALAR";
  124.     $self->{_content} = $_[1];
  125.     delete $self->{_content_ref};
  126.     }
  127.     delete $self->{_parts} unless $_[2];
  128. }
  129.  
  130.  
  131. sub add_content
  132. {
  133.     my $self = shift;
  134.     $self->_content unless exists $self->{_content};
  135.     my $chunkref = \$_[0];
  136.     $chunkref = $$chunkref if ref($$chunkref);  # legacy
  137.  
  138.     _utf8_downgrade($$chunkref);
  139.  
  140.     my $ref = ref($self->{_content});
  141.     if (!$ref) {
  142.     $self->{_content} .= $$chunkref;
  143.     }
  144.     elsif ($ref eq "SCALAR") {
  145.     ${$self->{_content}} .= $$chunkref;
  146.     }
  147.     else {
  148.     Carp::croak("Can't append to $ref content");
  149.     }
  150.     delete $self->{_parts};
  151. }
  152.  
  153. sub add_content_utf8 {
  154.     my($self, $buf)  = @_;
  155.     utf8::upgrade($buf);
  156.     utf8::encode($buf);
  157.     $self->add_content($buf);
  158. }
  159.  
  160. sub content_ref
  161. {
  162.     my $self = shift;
  163.     $self->_content unless exists $self->{_content};
  164.     delete $self->{_parts};
  165.     my $old = \$self->{_content};
  166.     my $old_cref = $self->{_content_ref};
  167.     if (@_) {
  168.     my $new = shift;
  169.     Carp::croak("Setting content_ref to a non-ref") unless ref($new);
  170.     delete $self->{_content};  # avoid modifying $$old
  171.     $self->{_content} = $new;
  172.     $self->{_content_ref}++;
  173.     }
  174.     $old = $$old if $old_cref;
  175.     return $old;
  176. }
  177.  
  178.  
  179. sub decoded_content
  180. {
  181.     my($self, %opt) = @_;
  182.     my $content_ref;
  183.     my $content_ref_iscopy;
  184.  
  185.     eval {
  186.  
  187.     require HTTP::Headers::Util;
  188.     my($ct, %ct_param);
  189.     if (my @ct = HTTP::Headers::Util::split_header_words($self->header("Content-Type"))) {
  190.         ($ct, undef, %ct_param) = @{$ct[-1]};
  191.         $ct = lc($ct);
  192.  
  193.         die "Can't decode multipart content" if $ct =~ m,^multipart/,;
  194.     }
  195.  
  196.     $content_ref = $self->content_ref;
  197.     die "Can't decode ref content" if ref($content_ref) ne "SCALAR";
  198.  
  199.     if (my $h = $self->header("Content-Encoding")) {
  200.         $h =~ s/^\s+//;
  201.         $h =~ s/\s+$//;
  202.         for my $ce (reverse split(/\s*,\s*/, lc($h))) {
  203.         next unless $ce || $ce eq "identity";
  204.         if ($ce eq "gzip" || $ce eq "x-gzip") {
  205.             require Compress::Zlib;
  206.             unless ($content_ref_iscopy) {
  207.             # memGunzip is documented to destroy its buffer argument
  208.             my $copy = $$content_ref;
  209.             $content_ref = \$copy;
  210.             $content_ref_iscopy++;
  211.             }
  212.             $content_ref = \Compress::Zlib::memGunzip($$content_ref);
  213.             die "Can't gunzip content" unless defined $$content_ref;
  214.         }
  215.         elsif ($ce eq "x-bzip2") {
  216.             require Compress::Bzip2;
  217.             $content_ref = Compress::Bzip2::decompress($$content_ref);
  218.             die "Can't bunzip content" unless defined $$content_ref;
  219.             $content_ref_iscopy++;
  220.         }
  221.         elsif ($ce eq "deflate") {
  222.             require Compress::Zlib;
  223.             my $out = Compress::Zlib::uncompress($$content_ref);
  224.             unless (defined $out) {
  225.             # "Content-Encoding: deflate" is supposed to mean the "zlib"
  226.                         # format of RFC 1950, but Microsoft got that wrong, so some
  227.                         # servers sends the raw compressed "deflate" data.  This
  228.                         # tries to inflate this format.
  229.             unless ($content_ref_iscopy) {
  230.                 # the $i->inflate method is documented to destroy its
  231.                 # buffer argument
  232.                 my $copy = $$content_ref;
  233.                 $content_ref = \$copy;
  234.                 $content_ref_iscopy++;
  235.             }
  236.  
  237.             my($i, $status) = Compress::Zlib::inflateInit(
  238.                 WindowBits => -Compress::Zlib::MAX_WBITS(),
  239.                         );
  240.             my $OK = Compress::Zlib::Z_OK();
  241.             die "Can't init inflate object" unless $i && $status == $OK;
  242.             ($out, $status) = $i->inflate($content_ref);
  243.             if ($status != Compress::Zlib::Z_STREAM_END()) {
  244.                 if ($status == $OK) {
  245.                 $self->push_header("Client-Warning" =>
  246.                     "Content might be truncated; incomplete deflate stream");
  247.                 }
  248.                 else {
  249.                 # something went bad, can't trust $out any more
  250.                 $out = undef;
  251.                 }
  252.             }
  253.             }
  254.             die "Can't inflate content" unless defined $out;
  255.             $content_ref = \$out;
  256.             $content_ref_iscopy++;
  257.         }
  258.         elsif ($ce eq "compress" || $ce eq "x-compress") {
  259.             die "Can't uncompress content";
  260.         }
  261.         elsif ($ce eq "base64") {  # not really C-T-E, but should be harmless
  262.             require MIME::Base64;
  263.             $content_ref = \MIME::Base64::decode($$content_ref);
  264.             $content_ref_iscopy++;
  265.         }
  266.         elsif ($ce eq "quoted-printable") { # not really C-T-E, but should be harmless
  267.             require MIME::QuotedPrint;
  268.             $content_ref = \MIME::QuotedPrint::decode($$content_ref);
  269.             $content_ref_iscopy++;
  270.         }
  271.         else {
  272.             die "Don't know how to decode Content-Encoding '$ce'";
  273.         }
  274.         }
  275.     }
  276.  
  277.     if ($ct && $ct =~ m,^text/,,) {
  278.         my $charset = $opt{charset} || $ct_param{charset} || $opt{default_charset} || "ISO-8859-1";
  279.         $charset = lc($charset);
  280.         if ($charset ne "none") {
  281.         require Encode;
  282.         if (do{my $v = $Encode::VERSION; $v =~ s/_//g; $v} < 2.0901 &&
  283.             !$content_ref_iscopy)
  284.         {
  285.             # LEAVE_SRC did not work before Encode-2.0901
  286.             my $copy = $$content_ref;
  287.             $content_ref = \$copy;
  288.             $content_ref_iscopy++;
  289.         }
  290.         $content_ref = \Encode::decode($charset, $$content_ref,
  291.              ($opt{charset_strict} ? Encode::FB_CROAK() : 0) | Encode::LEAVE_SRC());
  292.         }
  293.     }
  294.     };
  295.     if ($@) {
  296.     Carp::croak($@) if $opt{raise_error};
  297.     return undef;
  298.     }
  299.  
  300.     return $opt{ref} ? $content_ref : $$content_ref;
  301. }
  302.  
  303.  
  304. sub as_string
  305. {
  306.     my($self, $eol) = @_;
  307.     $eol = "\n" unless defined $eol;
  308.  
  309.     # The calculation of content might update the headers
  310.     # so we need to do that first.
  311.     my $content = $self->content;
  312.  
  313.     return join("", $self->{'_headers'}->as_string($eol),
  314.             $eol,
  315.             $content,
  316.             (@_ == 1 && length($content) &&
  317.              $content !~ /\n\z/) ? "\n" : "",
  318.         );
  319. }
  320.  
  321.  
  322. sub headers            { shift->{'_headers'};                }
  323. sub headers_as_string  { shift->{'_headers'}->as_string(@_); }
  324.  
  325.  
  326. sub parts {
  327.     my $self = shift;
  328.     if (defined(wantarray) && (!exists $self->{_parts} || ref($self->{_content}) eq "SCALAR")) {
  329.     $self->_parts;
  330.     }
  331.     my $old = $self->{_parts};
  332.     if (@_) {
  333.     my @parts = map { ref($_) eq 'ARRAY' ? @$_ : $_ } @_;
  334.     my $ct = $self->content_type || "";
  335.     if ($ct =~ m,^message/,) {
  336.         Carp::croak("Only one part allowed for $ct content")
  337.         if @parts > 1;
  338.     }
  339.     elsif ($ct !~ m,^multipart/,) {
  340.         $self->remove_content_headers;
  341.         $self->content_type("multipart/mixed");
  342.     }
  343.     $self->{_parts} = \@parts;
  344.     _stale_content($self);
  345.     }
  346.     return @$old if wantarray;
  347.     return $old->[0];
  348. }
  349.  
  350. sub add_part {
  351.     my $self = shift;
  352.     if (($self->content_type || "") !~ m,^multipart/,) {
  353.     my $p = HTTP::Message->new($self->remove_content_headers,
  354.                    $self->content(""));
  355.     $self->content_type("multipart/mixed");
  356.     $self->{_parts} = [$p];
  357.     }
  358.     elsif (!exists $self->{_parts} || ref($self->{_content}) eq "SCALAR") {
  359.     $self->_parts;
  360.     }
  361.  
  362.     push(@{$self->{_parts}}, @_);
  363.     _stale_content($self);
  364.     return;
  365. }
  366.  
  367. sub _stale_content {
  368.     my $self = shift;
  369.     if (ref($self->{_content}) eq "SCALAR") {
  370.     # must recalculate now
  371.     $self->_content;
  372.     }
  373.     else {
  374.     # just invalidate cache
  375.     delete $self->{_content};
  376.     delete $self->{_content_ref};
  377.     }
  378. }
  379.  
  380.  
  381. # delegate all other method calls the the _headers object.
  382. sub AUTOLOAD
  383. {
  384.     my $method = substr($AUTOLOAD, rindex($AUTOLOAD, '::')+2);
  385.     return if $method eq "DESTROY";
  386.  
  387.     # We create the function here so that it will not need to be
  388.     # autoloaded the next time.
  389.     no strict 'refs';
  390.     *$method = eval "sub { shift->{'_headers'}->$method(\@_) }";
  391.     goto &$method;
  392. }
  393.  
  394.  
  395. # Private method to access members in %$self
  396. sub _elem
  397. {
  398.     my $self = shift;
  399.     my $elem = shift;
  400.     my $old = $self->{$elem};
  401.     $self->{$elem} = $_[0] if @_;
  402.     return $old;
  403. }
  404.  
  405.  
  406. # Create private _parts attribute from current _content
  407. sub _parts {
  408.     my $self = shift;
  409.     my $ct = $self->content_type;
  410.     if ($ct =~ m,^multipart/,) {
  411.     require HTTP::Headers::Util;
  412.     my @h = HTTP::Headers::Util::split_header_words($self->header("Content-Type"));
  413.     die "Assert" unless @h;
  414.     my %h = @{$h[0]};
  415.     if (defined(my $b = $h{boundary})) {
  416.         my $str = $self->content;
  417.         $str =~ s/\r?\n--\Q$b\E--\r?\n.*//s;
  418.         if ($str =~ s/(^|.*?\r?\n)--\Q$b\E\r?\n//s) {
  419.         $self->{_parts} = [map HTTP::Message->parse($_),
  420.                    split(/\r?\n--\Q$b\E\r?\n/, $str)]
  421.         }
  422.     }
  423.     }
  424.     elsif ($ct eq "message/http") {
  425.     require HTTP::Request;
  426.     require HTTP::Response;
  427.     my $content = $self->content;
  428.     my $class = ($content =~ m,^(HTTP/.*)\n,) ?
  429.         "HTTP::Response" : "HTTP::Request";
  430.     $self->{_parts} = [$class->parse($content)];
  431.     }
  432.     elsif ($ct =~ m,^message/,) {
  433.     $self->{_parts} = [ HTTP::Message->parse($self->content) ];
  434.     }
  435.  
  436.     $self->{_parts} ||= [];
  437. }
  438.  
  439.  
  440. # Create private _content attribute from current _parts
  441. sub _content {
  442.     my $self = shift;
  443.     my $ct = $self->header("Content-Type") || "multipart/mixed";
  444.     if ($ct =~ m,^\s*message/,i) {
  445.     _set_content($self, $self->{_parts}[0]->as_string($CRLF), 1);
  446.     return;
  447.     }
  448.  
  449.     require HTTP::Headers::Util;
  450.     my @v = HTTP::Headers::Util::split_header_words($ct);
  451.     Carp::carp("Multiple Content-Type headers") if @v > 1;
  452.     @v = @{$v[0]};
  453.  
  454.     my $boundary;
  455.     my $boundary_index;
  456.     for (my @tmp = @v; @tmp;) {
  457.     my($k, $v) = splice(@tmp, 0, 2);
  458.     if (lc($k) eq "boundary") {
  459.         $boundary = $v;
  460.         $boundary_index = @v - @tmp - 1;
  461.         last;
  462.     }
  463.     }
  464.  
  465.     my @parts = map $_->as_string($CRLF), @{$self->{_parts}};
  466.  
  467.     my $bno = 0;
  468.     $boundary = _boundary() unless defined $boundary;
  469.  CHECK_BOUNDARY:
  470.     {
  471.     for (@parts) {
  472.         if (index($_, $boundary) >= 0) {
  473.         # must have a better boundary
  474.         $boundary = _boundary(++$bno);
  475.         redo CHECK_BOUNDARY;
  476.         }
  477.     }
  478.     }
  479.  
  480.     if ($boundary_index) {
  481.     $v[$boundary_index] = $boundary;
  482.     }
  483.     else {
  484.     push(@v, boundary => $boundary);
  485.     }
  486.  
  487.     $ct = HTTP::Headers::Util::join_header_words(@v);
  488.     $self->header("Content-Type", $ct);
  489.  
  490.     _set_content($self, "--$boundary$CRLF" .
  491.                     join("$CRLF--$boundary$CRLF", @parts) .
  492.             "$CRLF--$boundary--$CRLF",
  493.                         1);
  494. }
  495.  
  496.  
  497. sub _boundary
  498. {
  499.     my $size = shift || return "xYzZY";
  500.     require MIME::Base64;
  501.     my $b = MIME::Base64::encode(join("", map chr(rand(256)), 1..$size*3), "");
  502.     $b =~ s/[\W]/X/g;  # ensure alnum only
  503.     $b;
  504. }
  505.  
  506.  
  507. 1;
  508.  
  509.  
  510. __END__
  511.  
  512. =head1 NAME
  513.  
  514. HTTP::Message - HTTP style message (base class)
  515.  
  516. =head1 SYNOPSIS
  517.  
  518.  use base 'HTTP::Message';
  519.  
  520. =head1 DESCRIPTION
  521.  
  522. An C<HTTP::Message> object contains some headers and a content body.
  523. The following methods are available:
  524.  
  525. =over 4
  526.  
  527. =item $mess = HTTP::Message->new
  528.  
  529. =item $mess = HTTP::Message->new( $headers )
  530.  
  531. =item $mess = HTTP::Message->new( $headers, $content )
  532.  
  533. This constructs a new message object.  Normally you would want
  534. construct C<HTTP::Request> or C<HTTP::Response> objects instead.
  535.  
  536. The optional $header argument should be a reference to an
  537. C<HTTP::Headers> object or a plain array reference of key/value pairs.
  538. If an C<HTTP::Headers> object is provided then a copy of it will be
  539. embedded into the constructed message, i.e. it will not be owned and
  540. can be modified afterwards without affecting the message.
  541.  
  542. The optional $content argument should be a string of bytes.
  543.  
  544. =item $mess = HTTP::Message->parse( $str )
  545.  
  546. This constructs a new message object by parsing the given string.
  547.  
  548. =item $mess->headers
  549.  
  550. Returns the embedded C<HTTP::Headers> object.
  551.  
  552. =item $mess->headers_as_string
  553.  
  554. =item $mess->headers_as_string( $eol )
  555.  
  556. Call the as_string() method for the headers in the
  557. message.  This will be the same as
  558.  
  559.     $mess->headers->as_string
  560.  
  561. but it will make your program a whole character shorter :-)
  562.  
  563. =item $mess->content
  564.  
  565. =item $mess->content( $bytes )
  566.  
  567. The content() method sets the raw content if an argument is given.  If no
  568. argument is given the content is not touched.  In either case the
  569. original raw content is returned.
  570.  
  571. Note that the content should be a string of bytes.  Strings in perl
  572. can contain characters outside the range of a byte.  The C<Encode>
  573. module can be used to turn such strings into a string of bytes.
  574.  
  575. =item $mess->add_content( $bytes )
  576.  
  577. The add_content() methods appends more data bytes to the end of the
  578. current content buffer.
  579.  
  580. =item $mess->add_content_utf8( $string )
  581.  
  582. The add_content_utf8() method appends the UTF-8 bytes representing the
  583. string to the end of the current content buffer.
  584.  
  585. =item $mess->content_ref
  586.  
  587. =item $mess->content_ref( \$bytes )
  588.  
  589. The content_ref() method will return a reference to content buffer string.
  590. It can be more efficient to access the content this way if the content
  591. is huge, and it can even be used for direct manipulation of the content,
  592. for instance:
  593.  
  594.   ${$res->content_ref} =~ s/\bfoo\b/bar/g;
  595.  
  596. This example would modify the content buffer in-place.
  597.  
  598. If an argument is passed it will setup the content to reference some
  599. external source.  The content() and add_content() methods
  600. will automatically dereference scalar references passed this way.  For
  601. other references content() will return the reference itself and
  602. add_content() will refuse to do anything.
  603.  
  604. =item $mess->decoded_content( %options )
  605.  
  606. Returns the content with any C<Content-Encoding> undone and the raw
  607. content encoded to perl's Unicode strings.  If the C<Content-Encoding>
  608. or C<charset> of the message is unknown this method will fail by
  609. returning C<undef>.
  610.  
  611. The following options can be specified.
  612.  
  613. =over
  614.  
  615. =item C<charset>
  616.  
  617. This override the charset parameter for text content.  The value
  618. C<none> can used to suppress decoding of the charset.
  619.  
  620. =item C<default_charset>
  621.  
  622. This override the default charset of "ISO-8859-1".
  623.  
  624. =item C<charset_strict>
  625.  
  626. Abort decoding if malformed characters is found in the content.  By
  627. default you get the substitution character ("\x{FFFD}") in place of
  628. malformed characters.
  629.  
  630. =item C<raise_error>
  631.  
  632. If TRUE then raise an exception if not able to decode content.  Reason
  633. might be that the specified C<Content-Encoding> or C<charset> is not
  634. supported.  If this option is FALSE, then decoded_content() will return
  635. C<undef> on errors, but will still set $@.
  636.  
  637. =item C<ref>
  638.  
  639. If TRUE then a reference to decoded content is returned.  This might
  640. be more efficient in cases where the decoded content is identical to
  641. the raw content as no data copying is required in this case.
  642.  
  643. =back
  644.  
  645. =item $mess->parts
  646.  
  647. =item $mess->parts( @parts )
  648.  
  649. =item $mess->parts( \@parts )
  650.  
  651. Messages can be composite, i.e. contain other messages.  The composite
  652. messages have a content type of C<multipart/*> or C<message/*>.  This
  653. method give access to the contained messages.
  654.  
  655. The argumentless form will return a list of C<HTTP::Message> objects.
  656. If the content type of $msg is not C<multipart/*> or C<message/*> then
  657. this will return the empty list.  In scalar context only the first
  658. object is returned.  The returned message parts should be regarded as
  659. are read only (future versions of this library might make it possible
  660. to modify the parent by modifying the parts).
  661.  
  662. If the content type of $msg is C<message/*> then there will only be
  663. one part returned.
  664.  
  665. If the content type is C<message/http>, then the return value will be
  666. either an C<HTTP::Request> or an C<HTTP::Response> object.
  667.  
  668. If an @parts argument is given, then the content of the message will be
  669. modified. The array reference form is provided so that an empty list
  670. can be provided.  The @parts array should contain C<HTTP::Message>
  671. objects.  The @parts objects are owned by $mess after this call and
  672. should not be modified or made part of other messages.
  673.  
  674. When updating the message with this method and the old content type of
  675. $mess is not C<multipart/*> or C<message/*>, then the content type is
  676. set to C<multipart/mixed> and all other content headers are cleared.
  677.  
  678. This method will croak if the content type is C<message/*> and more
  679. than one part is provided.
  680.  
  681. =item $mess->add_part( $part )
  682.  
  683. This will add a part to a message.  The $part argument should be
  684. another C<HTTP::Message> object.  If the previous content type of
  685. $mess is not C<multipart/*> then the old content (together with all
  686. content headers) will be made part #1 and the content type made
  687. C<multipart/mixed> before the new part is added.  The $part object is
  688. owned by $mess after this call and should not be modified or made part
  689. of other messages.
  690.  
  691. There is no return value.
  692.  
  693. =item $mess->clear
  694.  
  695. Will clear the headers and set the content to the empty string.  There
  696. is no return value
  697.  
  698. =item $mess->protocol
  699.  
  700. =item $mess->protocol( $proto )
  701.  
  702. Sets the HTTP protocol used for the message.  The protocol() is a string
  703. like C<HTTP/1.0> or C<HTTP/1.1>.
  704.  
  705. =item $mess->clone
  706.  
  707. Returns a copy of the message object.
  708.  
  709. =item $mess->as_string
  710.  
  711. =item $mess->as_string( $eol )
  712.  
  713. Returns the message formatted as a single string.
  714.  
  715. The optional $eol parameter specifies the line ending sequence to use.
  716. The default is "\n".  If no $eol is given then as_string will ensure
  717. that the returned string is newline terminated (even when the message
  718. content is not).  No extra newline is appended if an explicit $eol is
  719. passed.
  720.  
  721. =back
  722.  
  723. All methods unknown to C<HTTP::Message> itself are delegated to the
  724. C<HTTP::Headers> object that is part of every message.  This allows
  725. convenient access to these methods.  Refer to L<HTTP::Headers> for
  726. details of these methods:
  727.  
  728.     $mess->header( $field => $val )
  729.     $mess->push_header( $field => $val )
  730.     $mess->init_header( $field => $val )
  731.     $mess->remove_header( $field )
  732.     $mess->remove_content_headers
  733.     $mess->header_field_names
  734.     $mess->scan( \&doit )
  735.  
  736.     $mess->date
  737.     $mess->expires
  738.     $mess->if_modified_since
  739.     $mess->if_unmodified_since
  740.     $mess->last_modified
  741.     $mess->content_type
  742.     $mess->content_encoding
  743.     $mess->content_length
  744.     $mess->content_language
  745.     $mess->title
  746.     $mess->user_agent
  747.     $mess->server
  748.     $mess->from
  749.     $mess->referer
  750.     $mess->www_authenticate
  751.     $mess->authorization
  752.     $mess->proxy_authorization
  753.     $mess->authorization_basic
  754.     $mess->proxy_authorization_basic
  755.  
  756. =head1 COPYRIGHT
  757.  
  758. Copyright 1995-2004 Gisle Aas.
  759.  
  760. This library is free software; you can redistribute it and/or
  761. modify it under the same terms as Perl itself.
  762.  
  763.